home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-10-28 | 25.5 KB | 1,029 lines |
- {
- $Id: crt.pp,v 1.5 1998/09/14 20:21:53 carl Exp $
- This file is part of the Free Pascal run time library.
- Copyright (c) 1998 by Nils Sjoholm and Carl Eric Codere
-
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
- **********************************************************************}
-
- {
- History:
-
- Bugs found in delline and insline, fixed.
- 5 Oct 1998
- nils.sjoholm@mailbox.swipnet.se
- }
-
- unit Crt;
-
- {--------------------------------------------------------------------}
- { LEFT TO DO: }
- {--------------------------------------------------------------------}
- { o Write special characters are not recognized }
- { o Write does not take care of window coordinates yet. }
- { o Read does not recognize the special editing characters }
- { o Read does not take care of window coordinates yet. }
- { o Readkey extended scancode is not correct yet }
- { o Color mapping only works for 4 colours }
- { o ClrScr, DeleteLine, InsLine do not work with window coordinates }
- {--------------------------------------------------------------------}
-
-
-
- Interface
-
- Const
- { Controlling consts }
- Flushing=false; {if true then don't buffer output}
- ScreenWidth = 80;
- ScreenHeight = 25;
-
- { CRT modes }
- BW40 = 0; { 40x25 B/W on Color Adapter }
- CO40 = 1; { 40x25 Color on Color Adapter }
- BW80 = 2; { 80x25 B/W on Color Adapter }
- CO80 = 3; { 80x25 Color on Color Adapter }
- Mono = 7; { 80x25 on Monochrome Adapter }
- Font8x8 = 256; { Add-in for ROM font }
-
- { Mode constants for 3.0 compatibility }
- C40 = CO40;
- C80 = CO80;
-
- {
- When using this color constants on the Amiga
- you can bet that they don't work as expected.
- You never know what color the user has on
- his Amiga. Perhaps we should do a check of
- the number of bitplanes (for number of colors)
-
- The normal 4 first pens for an Amiga are
-
- 0 LightGrey
- 1 Black
- 2 White
- 3 Blue
-
- }
-
- { Foreground and background color constants }
- Black = 1; { normal pen for amiga }
- Blue = 3; { windowborder color }
- Green = 15;
- Cyan = 7;
- Red = 4;
- Magenta = 5;
- Brown = 6;
- LightGray = 0; { canvas color }
-
- { Foreground color constants }
- DarkGray = 8;
- LightBlue = 9;
- LightGreen = 10;
- LightCyan = 11;
- LightRed = 12;
- LightMagenta = 13;
- Yellow = 14;
- White = 2; { third color on amiga }
-
- { Add-in for blinking }
- Blink = 128;
-
- {Other Defaults}
- LastMode : Word = 3;
- WindMin : Word = $0;
- WindMax : Word = $184f;
- { These don't change anything if they are modified }
- CheckSnow : Boolean = FALSE;
- DirectVideo: Boolean = FALSE;
- var
- TextAttr : BYTE;
- { CheckBreak have to make this one to a function for Amiga }
- CheckEOF : Boolean;
-
- Procedure AssignCrt(Var F: Text);
- Function KeyPressed: Boolean;
- Function ReadKey: Char;
- Procedure TextMode(Mode: Integer);
- Procedure Window(X1, Y1, X2, Y2: BYTE);
- Procedure GoToXy(X: byte; Y: byte);
- Function WhereX: Byte;
- Function WhereY: Byte;
- Procedure ClrScr;
- Procedure ClrEol;
- Procedure InsLine;
- Procedure DelLine;
- Procedure TextColor(Color: Byte);
- Procedure TextBackground(Color: Byte);
- Procedure LowVideo;
- Procedure HighVideo;
- Procedure NormVideo;
- Procedure Delay(DTime: Word);
- Procedure Sound(Hz: Word);
- Procedure NoSound;
-
- { Extra functions }
-
- Procedure CursorOn;
- Procedure CursorOff;
- Function CheckBreak: Boolean;
-
- Implementation
-
- {
- The definitions of TextRec and FileRec are in separate files.
- }
- {$i textrec.inc}
- {$i filerec.inc}
-
- var
- maxcols,maxrows : longint;
-
- CONST
- { This is used to make sure that readkey returns immediately }
- { if keypressed was used beforehand. }
- KeyPress : char = #0;
- _LVODisplayBeep = -96;
-
-
- Type
-
- pInfoData = ^tInfoData;
- tInfoData = packed record
- id_NumSoftErrors : Longint; { number of soft errors on disk }
- id_UnitNumber : Longint; { Which unit disk is (was) mounted on }
- id_DiskState : Longint; { See defines below }
- id_NumBlocks : Longint; { Number of blocks on disk }
- id_NumBlocksUsed : Longint; { Number of block in use }
- id_BytesPerBlock : Longint;
- id_DiskType : Longint; { Disk Type code }
- id_VolumeNode : Longint; { BCPL pointer to volume node }
- id_InUse : Longint; { Flag, zero if not in use }
- end;
-
- { * List Node Structure. Each member in a list starts with a Node * }
-
- pNode = ^tNode;
- tNode = packed Record
- ln_Succ, { * Pointer to next (successor) * }
- ln_Pred : pNode; { * Pointer to previous (predecessor) * }
- ln_Type : Byte;
- ln_Pri : Shortint; { * Priority, for sorting * }
- ln_Name : PChar; { * ID string, null terminated * }
- End; { * Note: Integer aligned * }
-
- { normal, full featured list }
-
- pList = ^tList;
- tList = packed record
- lh_Head : pNode;
- lh_Tail : pNode;
- lh_TailPred : pNode;
- lh_Type : Byte;
- l_pad : Byte;
- end;
-
- pMsgPort = ^tMsgPort;
- tMsgPort = packed record
- mp_Node : tNode;
- mp_Flags : Byte;
- mp_SigBit : Byte; { signal bit number }
- mp_SigTask : Pointer; { task to be signalled (TaskPtr) }
- mp_MsgList : tList; { message linked list }
- end;
-
- pMessage = ^tMessage;
- tMessage = packed record
- mn_Node : tNode;
- mn_ReplyPort : pMsgPort; { message reply port }
- mn_Length : Word; { message len in bytes }
- end;
-
- pIOStdReq = ^tIOStdReq;
- tIOStdReq = packed record
- io_Message : tMessage;
- io_Device : Pointer; { device node pointer }
- io_Unit : Pointer; { unit (driver private)}
- io_Command : Word; { device command }
- io_Flags : Byte;
- io_Error : Shortint; { error or warning num }
- io_Actual : Longint; { actual number of bytes transferred }
- io_Length : Longint; { requested number bytes transferred}
- io_Data : Pointer; { points to data area }
- io_Offset : Longint; { offset for block structured devices }
- end;
-
- pIntuiMessage = ^tIntuiMessage;
- tIntuiMessage = packed record
- ExecMessage : tMessage;
- IClass : Longint;
- Code : Word;
- Qualifier : Word;
- IAddress : Pointer;
- MouseX,
- MouseY : Word;
- Seconds,
- Micros : Longint;
- IDCMPWindow : Pointer;
- SpecialLink : pIntuiMessage;
- end;
-
- pWindow = ^tWindow;
- tWindow = packed record
- NextWindow : pWindow; { for the linked list in a screen }
- LeftEdge,
- TopEdge : Integer; { screen dimensions of window }
- Width,
- Height : Integer; { screen dimensions of window }
- MouseY,
- MouseX : Integer; { relative to upper-left of window }
- MinWidth,
- MinHeight : Integer; { minimum sizes }
- MaxWidth,
- MaxHeight : Word; { maximum sizes }
- Flags : Longint; { see below for defines }
- MenuStrip : Pointer; { the strip of Menu headers }
- Title : PChar; { the title text for this window }
- FirstRequest : Pointer; { all active Requesters }
- DMRequest : Pointer; { double-click Requester }
- ReqCount : Integer; { count of reqs blocking Window }
- WScreen : Pointer; { this Window's Screen }
- RPort : Pointer; { this Window's very own RastPort }
- BorderLeft,
- BorderTop,
- BorderRight,
- BorderBottom : Shortint;
- BorderRPort : Pointer;
- FirstGadget : Pointer;
- Parent,
- Descendant : pWindow;
- Pointer_ : Pointer; { sprite data }
- PtrHeight : Shortint; { sprite height (not including sprite padding) }
- PtrWidth : Shortint; { sprite width (must be less than or equal to 16) }
- XOffset,
- YOffset : Shortint; { sprite offsets }
- IDCMPFlags : Longint; { User-selected flags }
- UserPort,
- WindowPort : pMsgPort;
- MessageKey : pIntuiMessage;
- DetailPen,
- BlockPen : Byte; { for bar/border/gadget rendering }
- CheckMark : Pointer;
- ScreenTitle : PChar; { if non-null, Screen title when Window is active }
- GZZMouseX : Integer;
- GZZMouseY : Integer;
- GZZWidth : Integer;
- GZZHeight : Word;
- ExtData : Pointer;
- UserData : Pointer; { general-purpose pointer to User data extension }
- WLayer : Pointer;
- IFont : Pointer;
- MoreFlags : Longint;
- end;
-
- const
-
- M_LNM = 20; { linefeed newline mode }
- PMB_ASM = M_LNM + 1; { internal storage bit for AS flag }
- PMB_AWM = PMB_ASM + 1; { internal storage bit for AW flag }
- MAXTABS = 80;
- IECLASS_MAX = $15;
-
- type
-
- pKeyMap = ^tKeyMap;
- tKeyMap = packed record
- km_LoKeyMapTypes : Pointer;
- km_LoKeyMap : Pointer;
- km_LoCapsable : Pointer;
- km_LoRepeatable : Pointer;
- km_HiKeyMapTypes : Pointer;
- km_HiKeyMap : Pointer;
- km_HiCapsable : Pointer;
- km_HiRepeatable : Pointer;
- end;
-
-
-
- pConUnit = ^tConUnit;
- tConUnit = packed record
- cu_MP : tMsgPort;
- { ---- read only variables }
- cu_Window : Pointer; { (WindowPtr) intuition window bound to this unit }
- cu_XCP : Integer; { character position }
- cu_YCP : Integer;
- cu_XMax : Integer; { max character position }
- cu_YMax : Integer;
- cu_XRSize : Integer; { character raster size }
- cu_YRSize : Integer;
- cu_XROrigin : Integer; { raster origin }
- cu_YROrigin : Integer;
- cu_XRExtant : Integer; { raster maxima }
- cu_YRExtant : Integer;
- cu_XMinShrink : Integer; { smallest area intact from resize process }
- cu_YMinShrink : Integer;
- cu_XCCP : Integer; { cursor position }
- cu_YCCP : Integer;
-
- { ---- read/write variables (writes must must be protected) }
- { ---- storage for AskKeyMap and SetKeyMap }
-
- cu_KeyMapStruct : tKeyMap;
-
- { ---- tab stops }
-
- cu_TabStops : Array [0..MAXTABS-1] of Word;
- { 0 at start, -1 at end of list }
-
- { ---- console rastport attributes }
-
- cu_Mask : Shortint;
- cu_FgPen : Shortint;
- cu_BgPen : Shortint;
- cu_AOLPen : Shortint;
- cu_DrawMode : Shortint;
- cu_AreaPtSz : Shortint;
- cu_AreaPtrn : Pointer; { cursor area pattern }
- cu_Minterms : Array [0..7] of Byte; { console minterms }
- cu_Font : Pointer; { (TextFontPtr) }
- cu_AlgoStyle : Byte;
- cu_TxFlags : Byte;
- cu_TxHeight : Word;
- cu_TxWidth : Word;
- cu_TxBaseline : Word;
- cu_TxSpacing : Word;
-
- { ---- console MODES and RAW EVENTS switches }
-
- cu_Modes : Array [0..(PMB_AWM+7) div 8 - 1] of Byte;
- { one bit per mode }
- cu_RawEvents : Array [0..(IECLASS_MAX+7) div 8 - 1] of Byte;
- end;
-
- const
-
-
- CD_CURRX = 1;
- CD_CURRY = 2;
- CD_MAXX = 3;
- CD_MAXY = 4;
-
- CSI = chr($9b);
-
- SIGBREAKF_CTRL_C = 4096;
-
- function AllocVec( size, reqm : Longint ): Pointer;
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L size,d0
- MOVE.L reqm,d1
- MOVE.L _ExecBase, A6
- JSR -684(A6)
- MOVE.L (A7)+,A6
- MOVE.L d0,@RESULT
- end;
- end;
-
-
- function DoPkt(ID : pMsgPort;
- Action, Param1, Param2,
- Param3, Param4, Param5 : Longint) : Longint;
- begin
- asm
- MOVEM.L d2/d3/d4/d5/d6/d7/a6,-(A7)
- MOVE.L ID,d1
- MOVE.L Action,d2
- MOVE.L Param1,d3
- MOVE.L Param2,d4
- MOVE.L Param3,d5
- MOVE.L Param4,d6
- MOVE.L Param5,d7
- MOVE.L _DOSBase,A6
- JSR -240(A6)
- MOVEM.L (A7)+,d2/d3/d4/d5/d6/d7/a6
- MOVE.L d0,@RESULT
- end;
- end;
-
- procedure FreeVec( memory : Pointer );
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L memory,a1
- MOVE.L _ExecBase,A6
- JSR -690(A6)
- MOVE.L (A7)+,A6
- end;
- end;
-
-
- function GetConsoleTask : pMsgPort;
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L _DOSBase,A6
- JSR -510(A6)
- MOVE.L (A7)+,A6
- MOVE.L d0,@RESULT
- end;
- end;
-
-
- function GetMsg(port : pMsgPort): pMessage;
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L port,a0
- MOVE.L _ExecBase,A6
- JSR -372(A6)
- MOVE.L (A7)+,A6
- MOVE.L d0,@RESULT
- end;
- end;
-
- function ModifyIDCMP(window : pWindow;
- IDCMPFlags : Longint) : Boolean;
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L window,a0
- MOVE.L IDCMPFlags,d0
- MOVE.L _IntuitionBase,A6
- JSR -150(A6)
- MOVE.L (A7)+,A6
- TST.L d0
- bne @success
- bra @end
- @success:
- move.b #1,d0
- @end:
- move.b d0,@RESULT
- end;
- end;
-
- procedure ReplyMsg(mess : pMessage);
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L mess,a1
- MOVE.L _ExecBase,A6
- JSR -378(A6)
- MOVE.L (A7)+,A6
- end;
- end;
-
-
- function WaitPort(port : pMsgPort): pMessage;
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L port,a0
- MOVE.L _ExecBase,A6
- JSR -384(A6)
- MOVE.L (A7)+,A6
- MOVE.L d0,@RESULT
- end;
- end;
-
- procedure Delay_(ticks : Longint);
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L ticks,d1
- MOVE.L _DOSBase,A6
- JSR -198(A6)
- MOVE.L (A7)+,A6
- end;
- end;
-
- function SetSignal(newSignals, signalMask : Longint) : Longint;
- begin
- asm
- MOVE.L A6,-(A7)
- MOVE.L newSignals,d0
- MOVE.L signalMask,d1
- MOVE.L _ExecBase,A6
- JSR -306(A6)
- MOVE.L (A7)+,A6
- MOVE.L d0,@RESULT
- end;
- end;
-
- function OpenInfo : pInfoData;
- var
- port : pMsgPort;
- info : pInfoData;
- bptr, d4, d5, d6, d7 : Longint;
- begin
- info := pInfoData(AllocVec(SizeOf(tInfoData), 1));
-
- if info <> nil then begin
- port := GetConsoleTask;
- bptr := Longint(info) shr 2;
-
- if port <> nil then begin
- if DoPkt(port, $19, bptr, d4, d5, d6, d7) <> 0 then info := pInfoData(bptr shl 2)
- else port := nil;
- end;
-
- if port = nil then begin
- FreeVec(info);
- info := nil;
- end;
- end;
-
- OpenInfo := info;
- end;
-
- procedure CloseInfo(var info : pInfoData);
- begin
- if info <> nil then begin
- FreeVec(info);
- info := nil;
- end;
- end;
-
- function ConData(modus : byte) : integer;
- var
- info : pInfoData;
- theunit : pConUnit;
- pos : Longint;
- begin
- pos := 1;
- info := OpenInfo;
-
- if info <> nil then begin
- theunit := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit);
-
- case modus of
- CD_CURRX : pos := theunit^.cu_XCP;
- CD_CURRY : pos := theunit^.cu_YCP;
- CD_MAXX : pos := theunit^.cu_XMax;
- CD_MAXY : pos := theunit^.cu_YMax;
- end;
-
- CloseInfo(info);
- end;
-
- ConData := pos + 1;
- end;
-
- function WhereX : Byte;
- begin
- WhereX := Byte(ConData(CD_CURRX))-lo(windmin);
- end;
-
- function realx: byte;
- begin
- RealX := Byte(ConData(CD_CURRX));
- end;
-
- function realy: byte;
- begin
- RealY := Byte(ConData(CD_CURRY));
- end;
-
- function WhereY : Byte;
- begin
- WhereY := Byte(ConData(CD_CURRY))-hi(windmin);
- end;
-
- function screencols : integer;
- begin
- screencols := ConData(CD_MAXX);
- end;
-
- function screenrows : integer;
- begin
- screenrows := ConData(CD_MAXY);
- end;
-
-
- procedure Realgotoxy(x,y : integer);
- begin
- Write(CSI, y, ';', x, 'H');
- end;
-
-
- procedure gotoxy(x,y : byte);
- begin
- if (x<1) then
- x:=1;
- if (y<1) then
- y:=1;
- if y+hi(windmin)-2>=hi(windmax) then
- y:=hi(windmax)-hi(windmin)+1;
- if x+lo(windmin)-2>=lo(windmax) then
- x:=lo(windmax)-lo(windmin)+1;
- Write(CSI, y+hi(windmin), ';', x+lo(windmin), 'H');
- end;
-
-
- procedure CursorOff;
- begin
- Write(CSI,'0 p');
- end;
-
- procedure CursorOn;
- begin
- Write(CSI,'1 p');
- end;
-
- procedure ClrScr;
- begin
- Write(Chr($0c));
- end;
-
- function ReadKey : char;
- const
- IDCMP_VANILLAKEY = $00200000;
- IDCMP_RAWKEY = $00000400;
- var
- info : pInfoData;
- win : pWindow;
- imsg : pIntuiMessage;
- msg : pMessage;
- key : char;
- idcmp, vanil : Longint;
- begin
- key := #0;
- if KeyPress <> #0 then
- Begin
- ReadKey:=KeyPress;
- KeyPress:=#0;
- exit;
- end;
- info := OpenInfo;
-
- if info <> nil then begin
- win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
- idcmp := win^.IDCMPFlags;
- vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
-
- ModifyIDCMP(win, (idcmp or vanil));
-
- repeat
- msg := WaitPort(win^.UserPort);
- imsg := pIntuiMessage(GetMsg(win^.UserPort));
-
- if (imsg^.IClass = IDCMP_VANILLAKEY) then
- key := char(imsg^.Code)
- else
- if (imsg^.IClass = IDCMP_RAWKEY) then
- key := char(imsg^.Code);
-
- ReplyMsg(pMessage(imsg));
- until key <> #0;
-
- repeat
- msg := GetMsg(win^.UserPort);
-
- if msg <> nil then ReplyMsg(msg);
- until msg = nil;
-
- ModifyIDCMP(win, idcmp);
-
- CloseInfo(info);
- end;
-
- ReadKey := key;
- end;
-
- function KeyPressed : Boolean;
- const
- IDCMP_VANILLAKEY = $00200000;
- IDCMP_RAWKEY = $00000400;
- var
- info : pInfoData;
- win : pWindow;
- imsg : pIntuiMessage;
- msg : pMessage;
- idcmp, vanil : Longint;
- ispressed : Boolean;
- begin
- KeyPress := #0;
- ispressed := False;
- info := OpenInfo;
-
- if info <> nil then begin
- win := pWindow(pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_Window);
- idcmp := win^.IDCMPFlags;
- vanil := IDCMP_VANILLAKEY or IDCMP_RAWKEY;
-
- ModifyIDCMP(win, (idcmp or vanil));
-
- msg := WaitPort(win^.UserPort);
- imsg := pIntuiMessage(GetMsg(win^.UserPort));
-
- if (imsg^.IClass = IDCMP_VANILLAKEY) or (imsg^.IClass = IDCMP_RAWKEY) then
- Begin
- ispressed := true;
- KeyPress := char(imsg^.Code)
- end;
-
- ReplyMsg(pMessage(imsg));
-
- repeat
- msg := GetMsg(win^.UserPort);
-
- if msg <> nil then ReplyMsg(msg);
- until msg = nil;
-
- ModifyIDCMP(win, idcmp);
-
- CloseInfo(info);
- end;
-
- KeyPressed := ispressed;
- end;
-
- procedure TextColor(color : byte);
- begin
- TextAttr := (TextAttr and $70) or color;
- Write(CSI, '3', color, 'm');
- end;
-
- procedure TextBackground(color : byte);
- begin
- Textattr:=(textattr and $8f) or ((color and $7) shl 4);
- Write(CSI, '4', color, 'm');
- end;
-
- procedure Window(X1,Y1,X2,Y2: Byte);
- begin
- if (x1<1) or (x2>screencols) or (y2>screenrows) or
- (x1>x2) or (y1>y2) then
- exit;
- windmin:=(x1-1) or ((y1-1) shl 8);
- windmax:=(x2-1) or ((y2-1) shl 8);
- gotoxy(1,1);
- end;
-
-
-
-
-
- procedure DelLine;
- begin
- Write(CSI,'M');
- end;
-
- procedure ClrEol;
- begin
- Write(CSI,'K');
- end;
-
- procedure InsLine;
- begin
- Write(CSI,'L');
- end;
-
- procedure cursorbig;
- begin
- end;
-
- procedure lowvideo;
- begin
- end;
-
- procedure highvideo;
- begin
- end;
-
- procedure nosound;
- begin
- end;
-
- procedure sound(hz : word);
- begin
- end;
-
- procedure delay(DTime : Word);
- var
- dummy : Longint;
- begin
- dummy := trunc((real(DTime) / 1000.0) * 50.0);
- Delay_(dummy);
- end;
-
- function CheckBreak : boolean;
- begin
- if (SetSignal(0, 0) and SIGBREAKF_CTRL_C) = SIGBREAKF_CTRL_C then
- CheckBreak := true
- else
- CheckBreak := false;
- end;
-
- procedure textmode(mode : integer);
- begin
- lastmode:=mode;
- mode:=mode and $ff;
- windmin:=0;
- windmax:=(screencols-1) or ((screenrows-1) shl 8);
- maxcols:=screencols;
- maxrows:=screenrows;
- end;
-
- procedure normvideo;
- begin
- end;
-
- function GetTextBackground : byte;
- var
- info : pInfoData;
- pen : byte;
- begin
- pen := 1;
- info := OpenInfo;
-
- if info <> nil then begin
- pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_BgPen;
-
- CloseInfo(info);
- end;
-
- GetTextBackground := pen;
- end;
-
- function GetTextColor : byte;
- var
- info : pInfoData;
- pen : byte;
- begin
- pen := 1;
- info := OpenInfo;
-
- if info <> nil then begin
- pen := pConUnit((pIoStdReq(info^.id_InUse))^.io_Unit)^.cu_FgPen;
-
- CloseInfo(info);
- end;
-
- GetTextColor := pen;
- end;
-
-
- {*****************************************************************************
- Read and Write routines
- *****************************************************************************}
- { Problem here: Currently all these routines are not implemented because of how }
- { the console device works. Because w low level write is required to change the }
- { position of the cursor, and since the CrtWrite is assigned as the standard }
- { write routine, a recursive call will occur }
-
- { How to fix this: }
- { At startup make a copy of the Output handle, and then use this copy to make }
- { low level positioning calls. This does not seem to work yet. }
-
-
-
- Function CrtWrite(var f : textrec):integer;
-
- var
- i,col,row : longint;
- c : char;
- buf: array[0..1] of char;
-
- begin
- col:=realx;
- row:=realy;
- inc(row);
- inc(col);
- for i:=0 to f.bufpos-1 do
- begin
- c:=f.buffer[i];
- case ord(c) of
- 10 : begin
- inc(row);
- end;
- 13 : begin
- col:=lo(windmin)+1;
- end;
- 8 : if col>lo(windmin)+1 then
- begin
- dec(col);
- end;
- 7 : begin
- { beep }
- asm
- move.l a6,d6 { save base pointer }
- move.l _IntuitionBase,a6 { set library base }
- sub.l a0,a0
- jsr _LVODisplayBeep(a6)
- move.l d6,a6 { restore base pointer }
- end;
- end;
- else
- begin
- buf[0]:=c;
- realgotoxy(row,col);
- do_write(f.handle,longint(@buf[0]),1);
- inc(col);
- end;
- end;
- if col>lo(windmax)+1 then
- begin
- col:=lo(windmin)+1;
- inc(row);
- end;
- while row>hi(windmax)+1 do
- begin
- delline;
- dec(row);
- end;
- end;
- f.bufpos:=0;
- realgotoxy(row-1,col-1);
- CrtWrite:=0;
- end;
-
- Function CrtClose(Var F: TextRec): Integer;
- Begin
- F.Mode:=fmClosed;
- CrtClose:=0;
- End;
-
- Function CrtOpen(Var F: TextRec): Integer;
- Begin
- If F.Mode = fmOutput Then
- CrtOpen:=0
- Else
- CrtOpen:=5;
- End;
-
- Function CrtRead(Var F: TextRec): Integer;
- Begin
- f.bufend:=do_read(f.handle,longint(f.bufptr),f.bufsize);
- f.bufpos:=0;
- CrtRead:=0;
- End;
-
- Function CrtInOut(Var F: TextRec): Integer;
- Begin
- Case F.Mode of
- fmInput: CrtInOut:=CrtRead(F);
- fmOutput: CrtInOut:=CrtWrite(F);
- End;
- End;
-
- procedure assigncrt(var f : text);
- begin
- { TextRec(F).Mode:=fmClosed;
- TextRec(F).BufSize:=SizeOf(TextBuf);
- TextRec(F).BufPtr:=@TextRec(F).Buffer;
- TextRec(F).BufPos:=0;
- TextRec(F).OpenFunc:=@CrtOpen;
- TextRec(F).InOutFunc:=@CrtInOut;
- TextRec(F).FlushFunc:=@CrtInOut;
- TextRec(F).CloseFunc:=@CrtClose;
- TextRec(F).Name[0]:='.';
- TextRec(F).Name[1]:=#0;}
- end;
-
-
- var
- old_exit : pointer;
-
- procedure crt_exit;
- begin
- { Restore default colors }
- write(CSI,'0m');
- exitproc:=old_exit;
- end;
-
-
- Begin
- old_exit:=exitproc;
- exitproc:=@crt_exit;
- { load system variables to temporary variables to save time }
- maxcols:=screencols;
- maxrows:=screenrows;
- { Set the initial text attributes }
- { Text background }
- Textattr:=(textattr and $8f) or ((GetTextBackGround and $7) shl 4);
- { Text foreground }
- TextAttr := (TextAttr and $70) or GetTextColor;
- { set output window }
- windmax:=(maxcols-1) or (( maxrows-1) shl 8);
-
-
- { Get a copy of the standard }
- { output handle, and when using }
- { direct console calls, use this }
- { handle instead. }
- { assigncrt(Output);
- TextRec(Output).mode:=fmOutput;}
- end.
-
-
-
-
-
-